package br.ufrj.ppgi.infovis.util;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import br.ufrj.ppgi.infovis.mtgraph.Graph;
import br.ufrj.ppgi.infovis.mtgraph.GraphEdge;
import br.ufrj.ppgi.infovis.mtgraph.GraphNode;

public class XMLExport {

	private Graph graph;	
	
	private String pathName = "src/br/ufrj/ppgi/infovis/data/";
	private String exportName;
	private String template;
	private String atributo;
	private String ns = "http://www.w3.org/2001/XMLSchema-instance";
	private String schema = "esquema.xsd";
	
	public XMLExport(Graph graph, String exportName, String atributo){
		this.graph = graph;
		setExportName(exportName);
		setTemplate("dados_00.xml");
		this.atributo =atributo;  
	}
	
	public XMLExport(Graph graph){
		this.graph = graph;
		setExportName("dados_01.xml");
		setTemplate("dados_00.xml");
		this.atributo = "Academico";
	}
	
	/* Template do XML
	 * 
	 * <?xml version="1.0" encoding="UTF-8"?>
	 * <graph xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="esquema.xsd" >
	 * <graph-definition>Academia</graph-definition>
	 * <nodes>
	 * 	 <node id="1" type="Professor">
	 * 	 	<label>Adriana Vivacqua</label>
	 * 	  	<position>default</position>
	 * 	  </node>
	 * </nodes>
	}
	 * <edges>
	 * 	<edge a="1" b="4"/>
	 * </edges>
	 * </graph> 
	 * 
	 */
	
	
	public boolean Export() {
		
try {
			
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			
			//elemento raiz
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("graph");
			//rootElement = doc.createElementNS(ns, "graph");
			//TODO: ver como colocar o xsi esquema
			doc.appendChild(rootElement);
			
			
			//elemento graph-definition
			Element graphDef = doc.createElement("graph-definition");
			graphDef.appendChild(doc.createTextNode(atributo));
			rootElement.appendChild(graphDef);
			
			//elemento nodes
			Element nodes = doc.createElement("nodes");
			rootElement.appendChild(nodes);
			
			/*********************************************** 
			 * interar todos os nós dentro no Element nodes 
			 ***********************************************/
			
			GraphNode[] nodeList = graph.getNodeList();
				
			
			for (GraphNode node : nodeList) {
				//elemento node
				Element nodeEl = doc.createElement("node");
				nodes.appendChild(nodeEl);	
				
				
				//atributo
				nodeEl.setAttribute("id", node.getId());
				//TODO:  
				nodeEl.setAttribute("type", node.getType());
				//nodeEl.setAttribute("type", "Aluno");
						
				
				//elementos label
				Element label = doc.createElement("label");
				label.appendChild(doc.createTextNode(node.getLabel()));
				nodeEl.appendChild(label);
				
				//elementos position
				Element position = doc.createElement("position");
				//TODO: position.appendChild(doc.createTextNode(node.getPosition));
				position.appendChild(doc.createTextNode("default"));
				
				//System.out.println("id: "+node.getId()+" label: "+node.getLabel());
							
			}

			/****************************************************** 
			//TODO: interar todas ARESTAS dentro no Element edges 
			*******************************************************/
			
			GraphEdge[] edgeList = graph.getEdgeList();
			
			//elemento edges
			Element edges = doc.createElement("edges");
			rootElement.appendChild(edges);
			
			for (GraphEdge edge :edgeList){
				//elemento edge
				Element edgeEl = doc.createElement("edge");
				edges.appendChild(edgeEl);
				
				GraphNode[] edgeNodes = edge.getNodes();
				
				edgeEl.setAttribute("a", edgeNodes[0].getId());
				edgeEl.setAttribute("b", edgeNodes[1].getId());
					
			}

			// escrever o conteudo no arquivo xml
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			
			StreamResult result =  new StreamResult(System.out);
			
			//StreamResult result = new StreamResult(new File(getExportName()));
			
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");			

			transformer.transform(source, result);
	
	
			

			System.out.println("\n File Saved! \n Path "+getExportName());
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}	
		
		return true;
	}


	public String getExportName() {
		return exportName;
	}


	public void setExportName(String exportName) {
		this.exportName = pathName + exportName;
	}


	public String getTemplate() {
		return template;
	}


	public void setTemplate(String template) {
		this.template = pathName + template;
	}
	
}
